home *** CD-ROM | disk | FTP | other *** search
- ******************************************************************
- * COPYRIGHT (C) 1986 by Donald Krantz and James Stanley
- * - Note: This is a real, live, actual, registered copyright,
- * and should be treated as such. This source code is from
- * the book "68000 Assembly Language", Krantz and Stanley,
- * Addison-Wesley Publishing Company, Reading, MA, 1986.
- *
- * Permission granted by the authors for non-commercial use
- * in programs released to the public domain, as long as this
- * copyright notice remains attached and visible.
- *
- *****************************************************************
- * LINEED - Input line editor. Does editing into a string from
- * a CRT device. Supports default value prompting.
- *
- * ENTRY: P0.L is the address of the receiving string
- * P1.W is the screen line number to start editing
- * P2.W is the screen column.
- * P3.W is the max number of screen columns allowed
-
- #cursor.h
-
- .xdef lineed
- .xref case,cursor,putc,_getkey
-
- * The following symbol (and references thereto) required only if
- * using the VSCREEN virtual CRT interface.
- .xref sync_curs
-
- string equ 8 * Stack frame offsets
- line equ 12 * offset to editing line
- column equ 14 * offset to first editing column
- max equ 16 * offset to max editing cols.
-
- *****************************************************************
- lineed:
- link a6,#0 * Establish stack frame
- movem.l d0-d7/a0-a3,-(a7) * Save caller's registers.
- move.w max(a6),d7 * get maximum usable column
- add.w column(a6),d7 * compute max crt column
- subq.w #1,d7 * adjust for tests later
- clr.w D3 * Initialize string index
- move.l string(a6),a1 * get string base address
- loop:
- bsr update * update display
- bsr _getkey * Get next input key
- move.l #dispatch,a0 * setup case statement
- bsr case * case selector already in D0.
- bra loop * end of editing loop.
- *****************************************************************
- * Branches here when human presses RETURN key.
- finis:
- clr.b 0(a1,d3.w) * Terminate input string w/ null
- addq.l #4,a7 * Trash last return address
- movem.l (a7)+,d0-d7/a0-a3 * Restore caller's register
- unlk a6 * Restore caller's stack frame
- rts
- *****************************************************************
- * Branches here to display 'old' stuff past cursor.
- to_end:
- tst.b 0(a1,d3.w) * are we pointing at terminal?
- beq sk1_te * yes - no action required
- addq.w #1,d3 * move index up one.
- bra to_end * repeat
- sk1_te:
- rts
- *****************************************************************
- * Branches here to return cursor to start of line
- to_start:
- clr.w d3 * Set index to start
- rts
- *****************************************************************
- * branches here to move the cursor one character to the left.
- left:
- tst.w d3 * are we at start of line?
- beq exit_left * yes, let's blow this popstand
- subq.w #1,d3 * Index back one character
- exit_left:
- rts
- ****************************************************************
- * Moves the cursor one character to the right.
- right:
- tst.b 0(a1,d3.w) * Is there more stuff to display?
- beq exit_ri * Nope, we're done here.
- addq.w #1,d3 * add one to character index
- exit_ri:
- rts
- *****************************************************************
- * Branch here to delete one character to the right
- d_right:
- lea 0(a1,d3.w),a2 * load destination address
- tst.b (a2) * check for end of string
- beq exit_dr * no need to do anything.
- lea 1(a1,d3.w),a3 * load source address
- move.w max(a6),D1 * Get max char count
- sub d3,d1 * Compute transfer count
- lp0_dr:
- move.b (a3)+,(a2)+ * start moving the string in
- dbra d1,lp0_dr * do whole string.
- exit_dr:
- rts
- *****************************************************************
- * Branch here to delete one character to the left
- d_left:
- tst.w d3 * Are we at start of string?
- beq exit_dl * Yes, no action required.
- bsr left * Move cursor one char left
- bra d_right * re-use d_right code.
- exit_dl:
- rts
- *****************************************************************
- * Branch here to accept next key typed as a literal
- jamload:
- bsr _getkey * get next key
- bra othrs * shove it in.
- *****************************************************************
- * Inserts the typed character at the cursor.
- others:
- cmp.b #' ',d0 * Test for valid character
- blt exit_ot * No, less than $20, ignore
- othrs:
- move.w max(a6),D1 * Get max char count
- ext.l d1 * setup for address arithmetic
- lea -1(a1),a2 * load source address
- add.l d1,a2 * start at far end of string
- lea 0(a1),a3 * load destination address
- add.l d1,a3 * start at far end of string
- sub.w d3,d1 * get transfer count
- bra sk0_ot * do dec/tst before first xfer
- lp0_ot:
- move.b -(a2),-(a3) * start moving the string out
- sk0_ot:
- dbra d1,lp0_ot * loop over end of string.
- move.w max(a6),d1 * terminate string, in case of -
- clr.b (a1,d1.w) * overflow into terminal null
- move.b d0,0(a1,d3.w) * insert new character
- addq.w #1,d3 * move string index.
- exit_ot:
- rts
- *****************************************************************
- * prints the character in D0, expanding control chars as req.
- c_print:
- move.w d0,-(a7) * save character on stack
- cmp.b #$20,d0 * check if it's a control char
- bge sk0_cp * no, just print it.
- move.w #$005E,-(a7) * push a circumflex for a prefix
- bsr putc * print at cursor.
- addq.l #2,a7 * restore stack
- add.w #$0040,(a7) * make unprintable printable
- addq.w #1,d1 * increment column
- sk0_cp:
- bsr putc * put input char, already on stack
- addq.l #2,a7 * restore stack
- addq.w #1,d1 * increment column
- rts
- *****************************************************************
- * Prints the input string and updates cursor
- update:
- move.w line(a6),-(a7) * set cursor to start of line
- move.w column(a6),-(a7) this is X, above is Y
- bsr cursor * sets cursor to start
- addq.l #4,a7 * fix stack
- move.w column(a6),d1 * d1 will be cursor posit
- clr.w d4 * d4 will be counter
- lp0_sp:
- cmp.w d4,d3 * are we at cursor?
- bne sk0_sp * no, jump
- move.w d1,d5 * save screen cursor position
- sk0_sp:
- move.b 0(a1,d4.w),d0 * char to print
- beq sk1_sp * jump out if it's a null
- bsr c_print * output character
- addq.w #1,d4 * bump character counter
- cmp.w d1,d7 * test for end of area
- bge lp0_sp * repeat if there's room.
- sk1_sp:
- cmp d4,d3 * did we find cursor?
- ble sk2_sp * yes, we already found it.
- move.w d4,d3 * reset string counter
- subq.w #1,d3 * adjust because d4 incremented
- bra update * resync all the pointers
- sk2_sp:
- move.b #' ',d0 * blank rest of edit area
- cmp.w d1,d7 * did we output enough yet?
- blt sk3_sp * jump if we did
- bsr c_print * put a blank
- bra sk2_sp * try again
- sk3_sp:
- move.w line(a6),-(a7) * reset cursor
- move.w d5,-(a7) * this is cursor position
- bsr cursor * now tell the display
- addq.l #4,a7 * fix stack
- bsr sync_curs * only needed if using vscreen
- rts
- *****************************************************************
- * Input character dispatch table
- dispatch:
- dc.w 9 * Case options count
- dc.w return * when return => finis
- dc.l finis
- dc.w c_w_right * when c_w_right => to_end
- dc.l to_end
- dc.w c_w_left * when c_w_right => to_start
- dc.l to_start
- dc.w c_right * when c_right => right
- dc.l right
- dc.w c_left * when c_left => left
- dc.l left
- dc.w backsp * when backsp => left
- dc.l left
- dc.w left_del * when left_del => d_left
- dc.l d_left
- dc.w right_del * when right_del => d_right
- dc.l d_right
- dc.w lit_prefix * when lit_prefix => jamload
- dc.l jamload
- dc.l others * default case
-
- end